home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CICA 1995 August
/
CICA - The Ultimate Collection of Shareware for Windows (Disc 2) (August 1995).iso
/
disc2
/
programr
/
atre27.exe
/
ATREE_27
/
LFWIN
/
WINSYNAN.Y
< prev
next >
Wrap
Text File
|
1992-08-01
|
25KB
|
965 lines
%{
/*****************************************************************************
**** ****
**** winsynan.y ****
**** ****
**** atree release 2.7 for Windows ****
**** Adaptive Logic Network (ALN) simulation program. ****
**** Copyright (C) A. Dwelly, R. Manderscheid, M. Thomas, W.W. Armstrong ****
**** 1991, 1992 ****
**** ****
**** License: ****
**** A royalty-free license is granted for the use of this software for ****
**** NON_COMMERCIAL PURPOSES ONLY. The software may be copied and/or ****
**** modified provided this notice appears in its entirety and unchanged ****
**** in all derived source programs. Persons modifying the code are ****
**** requested to state the date, the changes made and who made them ****
**** in the modification history. ****
**** ****
**** Patent License: ****
**** The use of a digital circuit which transmits a signal indicating ****
**** heuristic responsibility is protected by U. S. Patent 3,934,231 ****
**** and others assigned to Dendronic Decisions Limited of Edmonton, ****
**** W. W. Armstrong, President. A royalty-free license is granted ****
**** by the company to use this patent for NON_COMMERCIAL PURPOSES to ****
**** adapt logic trees using this program and its modifications. ****
**** ****
**** Limited Warranty: ****
**** This software is provided "as is" without warranty of any kind, ****
**** either expressed or implied, including, but not limited to, the ****
**** implied warrantees of merchantability and fitness for a particular ****
**** purpose. The entire risk as to the quality and performance of the ****
**** program is with the user. Neither the authors, nor the ****
**** University of Alberta, its officers, agents, servants or employees ****
**** shall be liable or responsible in any way for any damage to ****
**** property or direct personal or consequential injury of any nature ****
**** whatsoever that may be suffered or sustained by any licensee, user ****
**** or any other party as a consequence of the use or disposition of ****
**** this software. ****
**** Modification history: ****
**** ****
**** 90.02.10 Initial implementation, A.Dwelly ****
**** 91.07.15 Release 2, Rolf Manderscheid ****
**** 91.07.15 Windows Port, M. Thomas ****
**** 92.04.27 atree v2.5, M. Thomas ****
**** 92.03.07 Release 2.6, Monroe Thomas ****
**** 92.01.08 Release 2.7, Monroe Thomas ****
**** ****
*****************************************************************************/
#include "atree.h"
#include "lf.h"
extern BOOL train_size_flag;
extern BOOL test_size_flag;
extern BOOL largest_flag;
extern BOOL smallest_flag;
extern BOOL fold_flag;
extern BOOL code_flag;
extern BOOL quant_flag;
extern prog_t prog;
FILE *yyin;
int line_no;
static BOOL first = TRUE;
static int tuple_ptr;
static int table_ptr;
static int table_size;
extern float far * far *tmp_table;
char szBuffer[120];
void
yyerrexit()
{
int i;
first = TRUE;
if (tmp_table != NULL)
Free(tmp_table);
for(i = 0; i < prog.total_dimensions; i++)
{
if (prog.trainset_sz && prog.train_table[i] != NULL)
Free(prog.train_table[i]);
if (prog.testset_sz && prog.test_table[i] != NULL)
Free(prog.test_table[i]);
}
if (prog.train_table != NULL)
Free(prog.train_table);
if (prog.test_table != NULL)
Free(prog.test_table);
if (prog.walk_step != NULL)
Free(prog.walk_step);
if (prog.code != NULL)
Free(prog.code);
}
%}
%token FUNCTION
%token DOMAINS
%token CODOMAINS
%token DIMENSIONS
%token EQUALS
%token INTEGER
%token QUANTIZATION
%token COLON
%token TRAINING
%token SET
/* use _SIZE instaed of SIZE so no conflict with windows.h */
%token _SIZE
%token TEST
%token CODING
%token LARGEST
%token SMALLEST
%token REAL
%token TREE
%token MIN
%token MAX
%token CORRECT
%token EPOCHS
%token VOTE
%token IDENTIFIER
%token STRING
%token SAVE
%token TO
%token LOAD
%token FROM
%token FOLDED
%% /* Program definition */
program : function_spec tree_spec
| tree_spec function_spec
;
function_spec : FUNCTION dimension codimension
{
int dim;
prog.total_dimensions = prog.dimensions + prog.codimensions;
prog.train_table = (float far * far *)
Malloc((unsigned)sizeof(float far *) * prog.total_dimensions);
MEMCHECK(prog.train_table);
prog.test_table = (float far * far *)
Malloc((unsigned)sizeof(float far *) * prog.total_dimensions);
MEMCHECK(prog.test_table);
prog.walk_step = (int far *)
Malloc((unsigned)sizeof(int) * prog.total_dimensions);
MEMCHECK(prog.walk_step);
prog.code = (LPCODE_T)
Malloc((unsigned)sizeof(code_t) * prog.total_dimensions);
MEMCHECK(prog.code);
tmp_table = (float far * far *)
Malloc((unsigned)sizeof(float far *) * prog.total_dimensions);
MEMCHECK(tmp_table);
for(dim = 0; dim < prog.total_dimensions; dim++)
{
prog.test_table[dim] = NULL;
prog.train_table[dim] = NULL;
tmp_table[dim] = NULL;
}
}
function_statements
dimension : DOMAINS DIMENSIONS EQUALS INTEGER
{
prog.dimensions = $4.i;
if (prog.dimensions < 1)
{
wsprintf(szBuffer, "number of domain dimensions must be at least 1, line %d.\n", line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
yyerrexit();
return(1);
}
}
codimension : /* empty */
{
prog.codimensions = 1;
}
| CODOMAINS DIMENSIONS EQUALS INTEGER
{
prog.codimensions = $4.i;
if (prog.codimensions < 1)
{
wsprintf(szBuffer, "number of codomain dimensions must be at least 1, line %d.\n", line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
yyerrexit();
return(1);
}
}
;
function_statements : function_statement
| function_statements function_statement
;
function_statement : quantization
| coding
| coding_io
| train_table_size
| train_table
| test_table_size
| test_table
| largest
| smallest
;
quantization : QUANTIZATION EQUALS
{
tuple_ptr = 0;
quant_flag = TRUE;
if (prog.load_code)
{
wsprintf(szBuffer,
"warning: coding(s) will be read from file '%s',\n\tquantization statement ignored, line %d.\n",
(LPSTR)prog.load_code,line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
}
quant_list
{
if (tuple_ptr > prog.total_dimensions)
{
prog.error = TRUE;
wsprintf(szBuffer, "too many elements in quantization list on line %d.\n", line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
if (tuple_ptr < prog.total_dimensions)
{
prog.error = TRUE;
wsprintf(szBuffer, "too few elements in quantization list on line %d.\n", line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
}
;
quant_list : INTEGER
{
if (tuple_ptr < prog.total_dimensions)
{
prog.code[tuple_ptr].vector_count = $1.i;
if ($1.i < 2)
{
prog.error = TRUE;
wsprintf(szBuffer, "must have at least 2 quantization levels, column %d.\n", tuple_ptr + 1);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
}
tuple_ptr++;
}
| quant_list INTEGER
{
if (tuple_ptr < prog.total_dimensions)
{
prog.code[tuple_ptr].vector_count = $2.i;
if ($2.i < 2)
{
prog.error = TRUE;
wsprintf(szBuffer, "must have at least 2 quantization levels, column %d.\n", tuple_ptr + 1);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
}
tuple_ptr++;
}
;
coding : CODING EQUALS
{
tuple_ptr = 0;
code_flag = TRUE;
if (prog.load_code)
{
wsprintf(szBuffer,
"warning: coding(s) will be read from file '%s',\n\tcoding statement ignored, line %d.\n",
(LPSTR)prog.load_code, line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
}
code_list
{
if (tuple_ptr > prog.total_dimensions)
{
prog.error = TRUE;
wsprintf(szBuffer, "too many elements in coding list on line %d.\n", line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
if (tuple_ptr < prog.total_dimensions)
{
prog.error = TRUE;
wsprintf(szBuffer, "too few elements in coding list on line %d.\n", line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
}
;
code_list : INTEGER COLON INTEGER
{
if (tuple_ptr < prog.total_dimensions)
{
prog.code[tuple_ptr].width = $1.i;
prog.walk_step[tuple_ptr] = $3.i;
if ($1.i < 1)
{
prog.error = TRUE;
wsprintf(szBuffer, "coding width must be at least 1, column %d.\n", tuple_ptr + 1);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
if ($3.i < 1)
{
prog.error = TRUE;
wsprintf(szBuffer, "coding distance must be at least 1, column %d.\n", tuple_ptr + 1);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
if ($3.i > $1.i)
{
prog.error = TRUE;
wsprintf(szBuffer, "coding distance must not be greater than coding width, column %d.\n", tuple_ptr + 1);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
}
tuple_ptr++;
}
| code_list INTEGER COLON INTEGER
{
if (tuple_ptr < prog.total_dimensions)
{
prog.code[tuple_ptr].width = $2.i;
prog.walk_step[tuple_ptr] = $4.i;
}
tuple_ptr++;
}
;
coding_io : SAVE CODING TO STRING
{
prog.save_code = $4.s;
}
| LOAD CODING FROM STRING
{
prog.load_code = $4.s;
if (code_flag || quant_flag)
{
wsprintf(szBuffer,
"warning: coding(s) will be read from file '%s',\n\tcoding and quantization statements ignored.\n",
(LPSTR)prog.load_code);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
}
;
train_table_size : TRAINING SET _SIZE EQUALS INTEGER
{
prog.trainset_sz = $5.i;
train_size_flag = TRUE;
}
;
train_table : TRAINING SET EQUALS
{
if (!train_size_flag)
{
wsprintf(szBuffer, "training set defined before size.\n");
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
yyerrexit();
return(1);
}
else
{
int dim;
tuple_ptr = 0;
table_ptr = 0;
table_size = prog.trainset_sz;
if (table_size > 0)
{
for (dim = 0; dim < prog.total_dimensions; dim++)
{
tmp_table[dim] = (float far *)
Malloc((unsigned) sizeof(float) * table_size);
MEMCHECK(tmp_table[dim]);
}
}
}
}
table
{
int dim;
if (tuple_ptr < prog.trainset_sz)
{
prog.error = TRUE;
wsprintf(szBuffer,"too few elements in training set.\n");
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
else if (tuple_ptr > prog.trainset_sz || table_ptr != 0)
{
wsprintf(szBuffer, "warning: extra elements in training set ignored.\n");
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
for (dim = 0; dim < prog.total_dimensions; dim++)
{
prog.train_table[dim] = (prog.trainset_sz ? tmp_table[dim] : NULL);
}
}
test_table_size : TEST SET _SIZE EQUALS INTEGER
{
prog.testset_sz = $5.i;
test_size_flag = TRUE;
}
;
test_table : TEST SET EQUALS
{
if (!test_size_flag)
{
wsprintf(szBuffer, "test set defined before size.\n");
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
yyerrexit();
return(1);
}
else
{
int dim;
tuple_ptr = 0;
table_ptr = 0;
table_size = prog.testset_sz;
if (table_size > 0)
{
for (dim = 0; dim < prog.total_dimensions; dim++)
{
tmp_table[dim] = (float far *)
Malloc((unsigned)sizeof(float) * table_size);
MEMCHECK(tmp_table[dim]);
}
}
}
}
table
{
int dim;
if (tuple_ptr < prog.testset_sz)
{
prog.error = TRUE;
wsprintf(szBuffer, "too few elements in test set.\n");
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
else if (tuple_ptr > prog.testset_sz || table_ptr != 0)
{
wsprintf(szBuffer, "warning: extra elements in test set ignored.\n");
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
for (dim = 0; dim < prog.total_dimensions; dim++)
{
prog.test_table[dim] = (prog.testset_sz ? tmp_table[dim] : NULL);
}
}
;
table : num
{
if (tuple_ptr < table_size)
{
tmp_table[table_ptr][tuple_ptr] = $1.f;
}
table_ptr++;
if (table_ptr == prog.total_dimensions)
{
table_ptr = 0;
tuple_ptr++;
}
}
| table num
{
if (tuple_ptr < table_size)
{
tmp_table[table_ptr][tuple_ptr] = $2.f;
}
table_ptr++;
if (table_ptr == prog.total_dimensions)
{
table_ptr = 0;
tuple_ptr++;
}
}
;
num : REAL
| INTEGER
{
$$.f = (float) $1.i;
}
;
largest : LARGEST EQUALS
{
tuple_ptr = 0;
largest_flag = TRUE;
}
largest_list
{
if (tuple_ptr > prog.total_dimensions)
{
prog.error = TRUE;
wsprintf(szBuffer, "too many elements in largest list on line %d.\n", line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
if (tuple_ptr < prog.total_dimensions)
{
prog.error = TRUE;
wsprintf(szBuffer, "too few elements in largest list on line %d.\n", line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
}
;
largest_list : num
{
if (tuple_ptr < prog.total_dimensions)
{
prog.code[tuple_ptr].high = $1.f;
}
tuple_ptr++;
}
| largest_list num
{
if (tuple_ptr < prog.total_dimensions)
{
prog.code[tuple_ptr].high = $2.f;
}
tuple_ptr++;
}
;
smallest : SMALLEST EQUALS
{
tuple_ptr = 0;
smallest_flag = TRUE;
}
smallest_list
{
if (tuple_ptr > prog.total_dimensions)
{
prog.error = TRUE;
wsprintf(szBuffer, "too many elements in smallest list on line %d.\n", line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
else if (tuple_ptr < prog.total_dimensions)
{
prog.error = TRUE;
wsprintf(szBuffer, "too few elements in smallest list on line %d.\n", line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
}
;
smallest_list : num
{
if (tuple_ptr < prog.total_dimensions)
{
prog.code[tuple_ptr].low = $1.f;
}
tuple_ptr++;
}
| smallest_list num
{
if (tuple_ptr < prog.total_dimensions)
{
prog.code[tuple_ptr].low = $2.f;
}
tuple_ptr++;
}
tree_spec : TREE tree_statements
tree_statements : tree_statement
| tree_statements tree_statement
tree_statement : tree_size
| tree_io
| min_correct
| max_epochs
| vote_no
;
tree_size : _SIZE EQUALS INTEGER
{
if (prog.load_tree)
{
wsprintf(szBuffer,
"warning: tree(s) will be read from file '%s',\n\ttree size statement ignored, line %d.\n",
(LPSTR)prog.load_tree, line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
else if ($3.i < 1)
{
wsprintf(szBuffer, "lf: tree size too small, line %d.\n",
line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
prog.error++;
}
else
{
prog.tree_sz = $3.i;
}
}
;
tree_io : SAVE TREE TO STRING
{
prog.save_tree = $4.s;
fold_flag = FALSE;
}
| SAVE FOLDED TREE TO STRING
{
prog.save_tree = $5.s;
fold_flag = TRUE;
}
| LOAD TREE FROM STRING
{
prog.load_tree = $4.s;
if (prog.tree_sz > 0)
{
wsprintf(szBuffer,
"lf: warning: tree(s) will be read from file '%s',\n\ttree size statement ignored, line %d.\n",
(LPSTR)prog.load_tree,line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
}
}
;
min_correct : MIN CORRECT EQUALS INTEGER
{
prog.min_correct = $4.i;
}
;
max_epochs : MAX EPOCHS EQUALS INTEGER
{
prog.max_epochs = $4.i;
}
;
vote_no : VOTE EQUALS INTEGER
{
if ($3.i % 2 != 1)
{
wsprintf(szBuffer,
"vote number must be odd, line %d.\n",
line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
yyerrexit();
return(1);
}
prog.vote = $3.i;
}
;
%%
yyerror(description)
char *description;
{
wsprintf(szBuffer, "%s, line %d.\n", (LPSTR)description, line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
prog.error = TRUE;
yyerrexit(); /* prepare for exit */
return(0);
}
/* Lexical states */
#define LEX_START 0
#define LEX_INT 1
#define LEX_DEC 2
#define LEX_IDENT 3
#define LEX_PUNCT 4
#define LEX_COMMENT 5
#define LEX_STRING 6
#define LEX_STOP 1000
#define ISCOMMENT(c) ((c) == '#')
#define MAX_LEN_BUF 1000
static char yytext[MAX_LEN_BUF];
static int lexstate;
static int nextchar;
static void
lexinit()
{
lexstate = LEX_START;
nextchar = getc(yyin);
}
isextdigit(c)
char c;
{
return((c == 'e') || (c == 'E') || (c == '+') || (c == '-') || isdigit(c));
}
iswhite(c)
char c;
{
if (c == '\n')
{
line_no++;
return(TRUE);
}
else
{
return((c == 0) || (c == ' ') || (c == '\t'));
}
}
static int
gettoken(str)
char *str;
{
int i;
int outcode;
static struct tok
{
char *token;
int code;
} toktab[] =
{
"function" , FUNCTION,
"dimension" , DIMENSIONS,
"dimensions" , DIMENSIONS,
"=" , EQUALS,
"quantization", QUANTIZATION,
":" , COLON,
"coding" , CODING,
"training" , TRAINING,
"set" , SET,
"size" , _SIZE,
"test" , TEST,
"tree" , TREE,
"minimum" , MIN,
"min" , MIN,
"maximum" , MAX,
"max" , MAX,
"correct" , CORRECT,
"epochs" , EPOCHS,
"largest" , LARGEST,
"smallest" , SMALLEST,
"domain" , DOMAINS,
"codomain" , CODOMAINS,
"vote" , VOTE,
"save" , SAVE,
"to" , TO,
"load" , LOAD,
"from" , FROM,
"folded" , FOLDED,
NULL ,0
};
outcode = IDENTIFIER;
for (i = 0; toktab[i].token != NULL; i++)
{
if (strcmp(str,toktab[i].token) == 0)
{
outcode = toktab[i].code;
break;
}
}
return(outcode);
}
static int
yylex()
{
int bufptr;
BOOL found_token;
int token;
found_token = FALSE;
bufptr = 0;
if (first)
{
first = FALSE;
lexinit();
}
while (!found_token)
{
switch (lexstate)
{
case LEX_START:
while (iswhite(nextchar))
{
nextchar = getc(yyin);
}
if (ISCOMMENT(nextchar))
{
nextchar = getc(yyin);
lexstate = LEX_COMMENT;
}
else if (isdigit(nextchar) || (nextchar == '-'))
{
yytext[bufptr++] = nextchar;
nextchar = getc(yyin);
lexstate = LEX_INT;
}
else if (isalpha(nextchar))
{
yytext[bufptr++] = nextchar;
nextchar = getc(yyin);
lexstate = LEX_IDENT;
}
else if (nextchar == '"')
{
nextchar = getc(yyin);
lexstate = LEX_STRING;
}
else if (ispunct(nextchar))
{
yytext[bufptr++] = nextchar;
nextchar = getc(yyin);
lexstate = LEX_PUNCT;
}
else if (nextchar == EOF)
{
lexstate = LEX_STOP;
}
else
{
wsprintf(szBuffer,
"unrecognized character '%c', line %d.\n",
nextchar, line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
yyerrexit();
return(YYEXIT);
}
break;
case LEX_INT:
while (isdigit(nextchar))
{
yytext[bufptr++] = nextchar;
nextchar = getc(yyin);
}
if (nextchar == '.')
{
yytext[bufptr++] = nextchar;
nextchar = getc(yyin);
lexstate = LEX_DEC;
}
else
{
yytext[bufptr] = 0;
yylval.i = atoi(yytext);
token = INTEGER;
found_token = TRUE;
}
break;
case LEX_DEC:
while (isextdigit(nextchar))
{
yytext[bufptr++] = nextchar;
nextchar = getc(yyin);
}
yytext[bufptr] = 0;
sscanf(yytext,"%g",&yylval.f);
token = REAL;
found_token = TRUE;
break;
case LEX_IDENT:
while (isalpha(nextchar) || isdigit(nextchar))
{
yytext[bufptr++] = nextchar;
nextchar = getc(yyin);
}
yytext[bufptr] = 0;
token = gettoken(yytext);
found_token = TRUE;
break;
case LEX_STRING:
while (nextchar != '"')
{
if (nextchar == '\n')
{
wsprintf(szBuffer,
"newline in string, line %d.\n",
line_no);
MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
return (YYEXIT);
}
yytext[bufptr++] = nextchar;
nextchar = getc(yyin);
}
nextchar = getc(yyin); /* skip closing quote */
yytext[bufptr] = 0;
yylval.s = strdup(yytext);
token = STRING;
found_token = TRUE;
break;
case LEX_PUNCT:
yytext[bufptr] = 0;
token = gettoken(yytext);
found_token = TRUE;
break;
case LEX_COMMENT:
while (nextchar != '\n')
{
nextchar = getc(yyin);
}
lexstate = LEX_START;
break;
case LEX_STOP:
token = 0;
found_token = TRUE;
first = TRUE;
break;
}
}
if (lexstate != LEX_STOP)
{
lexstate = LEX_START;
}
return(token);
}